//
//  DiffableTableView.swift
//  ShimaPlayer
//
//  Created by michael on 2025/7/17.
//

import UIKit

class TableView<Section, Row, Cell: UITableViewCell>: UIView, UITableViewDataSource, UITableViewDelegate
where Section: Hashable, Row: Hashable, Cell: ReusableCell {
    
    // MARK: - 类型定义
    typealias CellConfigurator = (Cell, Row, IndexPath) -> Void
    typealias SelectionHandler = (Row, IndexPath) -> Void
    
    // MARK: - 属性
    private let tableView: UITableView
    private var sections: [Section] = []
    private var rowsForSection: (Int) -> [Row] = { _ in [] }
    private var cellConfigurator: CellConfigurator = { _, _, _ in }
    private var selectionHandler: SelectionHandler?
    
    // 单元格间距相关属性
    private var sectionInsets: UIEdgeInsets = .zero
    private var cellSpacing: CGFloat = 0
    
    // MARK: - 初始化
    init(style: UITableView.Style = .plain) {
        self.tableView = UITableView(frame: .zero, style: style)
        super.init(frame: .zero)
        setupTableView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 配置方法
    private func setupTableView() {
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(Cell.self, forCellReuseIdentifier: Cell.reuseIdentifier)
        
        addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: topAnchor),
            tableView.bottomAnchor.constraint(equalTo: bottomAnchor),
            tableView.leadingAnchor.constraint(equalTo: leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }
    
    // MARK: - UITableViewDataSource 方法
    func numberOfSections(in tableView: UITableView) -> Int {
        sections.isEmpty ? 1 : sections.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        rowsForSection(section).count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: Cell.reuseIdentifier, for: indexPath) as! Cell
        let row = rowsForSection(indexPath.section)[indexPath.row]
        cellConfigurator(cell, row, indexPath)
        return cell
    }
    
    // MARK: - UITableViewDelegate 方法
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let row = rowsForSection(indexPath.section)[indexPath.row]
        selectionHandler?(row, indexPath)
        tableView.deselectRow(at: indexPath, animated: true)
    }
    
    // 实现单元格间距的代理方法
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 0 && sectionInsets.top > 0 {
            let headerView = UIView()
            headerView.backgroundColor = .clear
            return headerView
        }
        return nil
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return section == 0 ? sectionInsets.top : 0
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let isLastSection = section == (sections.isEmpty ? 0 : sections.count - 1)
        if isLastSection && sectionInsets.bottom > 0 {
            let footerView = UIView()
            footerView.backgroundColor = .clear
            return footerView
        }
        return nil
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        let isLastSection = section == (sections.isEmpty ? 0 : sections.count - 1)
        return isLastSection ? sectionInsets.bottom : cellSpacing
    }
    
    // MARK: - 公开API
    func sections(_ sections: [Section]) -> Self {
        self.sections = sections
        return self
    }
    
    func rowsForSection(_ provider: @escaping (Int) -> [Row]) -> Self {
        self.rowsForSection = provider
        return self
    }
    
    func configureCell(_ configurator: @escaping CellConfigurator) -> Self {
        self.cellConfigurator = configurator
        return self
    }
    
    func onSelect(_ handler: @escaping SelectionHandler) -> Self {
        self.selectionHandler = handler
        return self
    }
    
    func reloadData() {
        tableView.reloadData()
    }
    
    // MARK: - 高级功能
    func backgroundColor(_ color: UIColor?) -> Self {
        tableView.backgroundColor = color
        return self
    }
    func rowHeight(_ height: CGFloat) -> Self {
        tableView.rowHeight = height
        return self
    }
    
    func estimatedRowHeight(_ height: CGFloat) -> Self {
        tableView.estimatedRowHeight = height
        return self
    }
    
    func separatorStyle(_ style: UITableViewCell.SeparatorStyle) -> Self {
        tableView.separatorStyle = style
        return self
    }

    func separatorInset(_ inset: UIEdgeInsets) -> Self {
        tableView.separatorInset = inset
        return self
    }
    
    func tableViewHeader(_ header: UIView?) -> Self {
        tableView.tableHeaderView = header
        return self
    }

    func tableViewFooter(_ footer: UIView?) -> Self {
        tableView.tableFooterView = footer
        return self
    }
    
    func registerHeaderFooterView<View: UITableViewHeaderFooterView & ReusableCell>(_ viewType: View.Type) -> Self {
        tableView.register(viewType, forHeaderFooterViewReuseIdentifier: View.reuseIdentifier)
        return self
    }
    
    // MARK: - 单元格间距设置
    
    /// 设置表格的内边距，影响表格四周的间距
    /// - Parameter insets: 表格内边距
    /// - Returns: 自身实例，用于链式调用
    func sectionInsets(_ insets: UIEdgeInsets) -> Self {
        self.sectionInsets = insets
        return self
    }
    
    /// 设置单元格之间的垂直间距
    /// - Parameter spacing: 垂直间距值
    /// - Returns: 自身实例，用于链式调用
    func cellSpacing(_ spacing: CGFloat) -> Self {
        self.cellSpacing = spacing
        return self
    }
    
    /// 同时设置表格内边距和单元格间距
    /// - Parameters:
    ///   - insets: 表格内边距
    ///   - spacing: 单元格间距
    /// - Returns: 自身实例，用于链式调用
    func spacing(insets: UIEdgeInsets, between: CGFloat) -> Self {
        self.sectionInsets = insets
        self.cellSpacing = between
        return self
    }
}

// MARK: - 可复用单元格协议
protocol ReusableCell: AnyObject {
    static var reuseIdentifier: String { get }
}

extension ReusableCell {
    static var reuseIdentifier: String {
        return String(describing: self)
    }
}

extension UITableViewCell: ReusableCell {}
extension UITableViewHeaderFooterView: ReusableCell {}

